/**********************************************************
    COPYRIGHT
        KND, Inc. (c) 2011
    CLASS NAME
        platform_decode.c
    DEPENDENCY

    HISTORY
		02/29/2012, created by Guangxing Liu
**********************************************************/
#include "platform_decode.h"
#include "platform_config.h"
#include "platform_uart.h"
#include "platform_gpio.h"
#include "lpc177x_8x_timer.h"
#include "lpc177x_8x_emc.h"
#include "platform_timer.h"
#include "platform_pwm.h"
#include "platform_adc.h"

extern volatile hyacinth_service *p_gpio_service;
extern volatile hyacinth_service *p_pwm_service;
extern volatile hyacinth_service *p_adc_service;
extern volatile platform_timer_counter decode_pause_timer;
extern volatile unsigned char g_begin_decode_command;

volatile int platform_decode_value[DECODE_MAX_PORT_NUM];

volatile platform_decode_adc_map decode_adc_map[DECODE_ADC_CHANNEL_NUM];

volatile platform_decode_port_map pdpm[DECODE_MAX_PORT_NUM]={{1,13,0,0,0,0},{1,2,0,1,0,0}};

volatile platform_decode_command_index pdci[DECODE_MAX_COMMAND_INDEX];
/************************************************************************
	FUNCTION NAME : platform_decode_init
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		Platform decode init
************************************************************************/
void platform_decode_init(void)
{
	memset(pdci,0,sizeof(platform_decode_command_index)*DECODE_MAX_COMMAND_INDEX);
	memset(platform_decode_value,0,sizeof(int)*DECODE_MAX_PORT_NUM);
	memset(decode_adc_map,0,sizeof(platform_decode_port_map)*DECODE_ADC_CHANNEL_NUM);
	
}

/************************************************************************
	FUNCTION NAME : platform_decode_device_open
	INPUTS: 
 		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		cpld Device Open
************************************************************************/
DeviceHandle platform_decode_device_open(void)
{
	platform_decode_app_call* handle = (platform_decode_app_call*)malloc(sizeof(platform_decode_app_call));
	if(handle)
	{
		handle->iOpt = Platform_Decode_App_Call_None;
	}
	return (DeviceHandle)handle;
 }	

/************************************************************************
	FUNCTION NAME : platform_decode_device_close
	INPUTS: 
		DeviceHandle handle
	OUTPUTS:	
		none
	DESCRIPTION:	
		decode Device Close
************************************************************************/
int platform_decode_device_close(DeviceHandle handle)
{
	platform_decode_app_call* me = (platform_decode_app_call*)handle;
	if(me)
	{
		free(me);
	}
	return 0;
	
}/************************************************************************
	FUNCTION NAME : platform_decode_device_ioctl
	INPUTS: 
		DeviceHandle handle, const char *params
	OUTPUTS:	
		none
	DESCRIPTION:	
		decode Device Control
************************************************************************/
int platform_decode_device_ioctl(DeviceHandle handle, const char *params)
{
	platform_decode_app_call* me = (platform_decode_app_call*)handle;
	
	switch(*params)
	{
		case '0':
			me->iOpt = Platform_Decode_App_Call_Decode_Init;
			return 0;
		case '1':
			me->iOpt = Platform_Decode_App_Call_Decode_WritePin;
			return 0;
		case '2':
			me->iOpt = Platform_Decode_App_Call_Decode_ReadPin;
			return 0;
		default:
			platform_printf("ERROR--platform_decode_device_ioctl unkown params: %s\r\n",params);
			break;
	}

	return -1;
}

/************************************************************************
	FUNCTION NAME :platform_decode_device_read
	INPUTS: 
		DeviceHandle handle, char *buf, int len
	OUTPUTS:	
		none
	DESCRIPTION:	
		decode Device Read
************************************************************************/
int platform_decode_device_read(DeviceHandle handle, void *buf, int len)
{
	platform_decode_app_call* me = (platform_decode_app_call*)handle;
	
	if(!me || !buf)
		return -1;
	switch(me->iOpt)
	{
		case Platform_Decode_App_Call_Decode_ReadPin:			
	         	return 0;
		default:
			platform_printf("ERROR--platform_decode_device_read unkown params: %s\r\n",me->iOpt);
			break;
	}
	
	return -1;

}

/************************************************************************
	FUNCTION NAME : platform_decode_device_write
	INPUTS: 
		DeviceHandle handle,  const char *buf, int len
	OUTPUTS:	
		none
	DESCRIPTION:	
		decode Device Write
************************************************************************/
int platform_decode_device_write(DeviceHandle handle,  void *buf, int len)
{
	platform_decode_app_call* me = (platform_decode_app_call*)handle;
	if(!me || !buf)
		return -1;
	switch(me->iOpt)
	{
		case Platform_Decode_App_Call_Decode_Init:
			{
				
			}
			return 0;
		case Platform_Decode_App_Call_Decode_WritePin:
			{
				volatile platform_decode_config* p_config = (platform_decode_config*)buf;

				switch(p_config->pin_func)
				{
					case DECODE_GPIO:
						{
							
							if(p_gpio_service)
							{
								switch(p_config->pin_action)
								{
									case DECODE_SET_DIR:
										{
											volatile platform_gpio_setdir p_gpio_config;
											
											p_gpio_config.dir = p_config->dir;
											p_gpio_config.gpio_num = p_config->port_num;
											p_gpio_config.gpio.gpio_pin = p_config->pin_num;
									
											p_gpio_service->device_interface.ioctl(p_gpio_service->hanle,platform_gpio_app_call_device_op_setiodir);
											p_gpio_service->device_interface.write(p_gpio_service->hanle,(void*)&p_gpio_config,sizeof(platform_gpio_setdir));
										}
										break;
									case DECODE_SET_VALUE:
										{
											volatile platform_gpio_setvalue p_gpio_value;
											
											p_gpio_value.gpio_num = p_config->port_num;
											p_gpio_value.gpio.gpio_pin = p_config->pin_num;
											p_gpio_value.value = p_config->pin_value;

											p_gpio_service->device_interface.ioctl(p_gpio_service->hanle,platform_gpio_app_call_device_op_setiovalue);
											p_gpio_service->device_interface.write(p_gpio_service->hanle,(void*)&p_gpio_value,sizeof(platform_gpio_setvalue));
										}
										break;
									case DECODE_GET_VALUE:
										break;
									default:
										break;
								}

								
							}
																				
						}
						break;
					case DECODE_PWM:
						{
							if(p_pwm_service)
							{
								switch(p_config->pin_action)
								{
									case DECODE_SET_DIR:
										{
											volatile platform_pwm_config p_pwm_config;

											p_pwm_config.pwm_no = p_config->pwm_port;
											p_pwm_config.pwm_channel= p_config->pwm_channel;
											p_pwm_config.pwm_value =p_config->pin_value;

											p_pwm_service->device_interface.ioctl(p_pwm_service->hanle,platform_pwm_app_call_device_op_pwminit);
											p_pwm_service->device_interface.write(p_pwm_service->hanle,(void*)&p_pwm_config,sizeof(platform_pwm_config));

										}
										break;
									case DECODE_SET_VALUE:
										{
											volatile platform_pwm_config p_pwm_config;

											p_pwm_config.pwm_no = p_config->pwm_port;
											p_pwm_config.pwm_channel= p_config->pwm_channel;
											p_pwm_config.pwm_value =p_config->pin_value;

											p_pwm_service->device_interface.ioctl(p_pwm_service->hanle,platform_pwm_app_call_device_op_setpwmvalue);
											p_pwm_service->device_interface.write(p_pwm_service->hanle,(void*)&p_pwm_config,sizeof(platform_pwm_config));												
										}
										break;
									default:
										 break;
								}
							}
						}
						break;
					case DECODE_ADC:
						{
							if(p_adc_service)
							{
								switch(p_config->pin_action)
								{
									case DECODE_SET_DIR:
										{
											volatile platform_adc_config p_adc_config;

											p_adc_config.channel = p_config->adc_channel;

											p_adc_config.channel_intr= p_config->adc_channel;

											decode_adc_map[p_config->adc_channel].v_index = p_config->v_index;
											
											p_adc_service->device_interface.ioctl(p_adc_service->hanle,platform_adc_app_call_device_op_adcconfig);

											p_adc_service->device_interface.write(p_adc_service->hanle,(void*)&p_adc_config,sizeof(platform_adc_config));	
										}
										break;
									default:
										break;
								}
							}
						}
						break;
					case DECODE_COUNTER:
						{
							switch(p_config->pin_action)
							{
								case DECODE_PAUSE:
									{
										g_begin_decode_command =0;
										decode_pause_timer.counter =0;
										decode_pause_timer.counter_timeout = p_config->pin_value*1000/BASE_TIME_TICK/8;
										decode_pause_timer.start =1;
									}
									break;
								default:
									break;
							}
						}
						break;
					case DECODE_LD:
						{
						}
						break;
					default:
						break;
				}
			}
			return 0;
		default:
			platform_printf("ERROR--platform_decode_device_write unkown params: %s\r\n",me->iOpt);
			break;
	}
	return -1;

}
/************************************************************************
	FUNCTION NAME : platform_init_decode_device
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		decode Device Init
************************************************************************/
void platform_init_decode_device(void)
{
	DeviceInterface decode= {
                               platform_decode_device_open,
                               platform_decode_device_close,
                               platform_decode_device_ioctl,
                               platform_decode_device_read,
                               platform_decode_device_write
                              };


	hyacinth_install_device(DECODE_DEVICE,&decode);
}

/************************************************************************
	FUNCTION NAME : platform_finit_decode_device
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		decode Device Finit
************************************************************************/
void platform_finit_decode_device(void)
{
	hyacinth_uninstall_device(DECODE_DEVICE);
}


